package com.onlinelearn.paymentservice.service;

import com.onlinelearn.courseservice.service.CourseService;
import com.onlinelearn.notifyservice.service.NotificationTriggerService;
import com.onlinelearn.paymentservice.model.PaymentOrder;
import com.onlinelearn.paymentservice.model.PaymentOrderStatus;
import com.onlinelearn.paymentservice.model.PaymentMethod;
import com.onlinelearn.paymentservice.repository.PaymentOrderRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;

@Service
public class PaymentOrderService {
    @Autowired
    private PaymentOrderRepository orderRepository;

    @Autowired
    private CourseService courseService;

    @Autowired
    private NotificationTriggerService notificationService;

    @Autowired
    private PaymentGatewayService paymentGateway;

    @Transactional
    public PaymentOrder createOrder(Long studentId, Long courseId) {
        Course course = courseService.findById(courseId);

        PaymentOrder order = new PaymentOrder();
        order.setStudentId(studentId);
        order.setCourseId(courseId);
        order.setAmount(course.getPrice());
        order.setStatus(PaymentOrderStatus.PENDING);
        order.setOrderTime(LocalDateTime.now());
        order.setExpirationTime(LocalDateTime.now().plusMinutes(30));

        return orderRepository.save(order);
    }

    @Transactional
    public PaymentOrder processPayment(Long orderId, PaymentMethod method) {
        PaymentOrder order = orderRepository.findById(orderId)
            .orElseThrow(() -> new OrderNotFoundException(orderId));

        validateOrderBeforePayment(order);

        try {
            PaymentResult result = paymentGateway.processPayment(order, method);

            if (result.isSuccess()) {
                order.setStatus(PaymentOrderStatus.PAID);
                order.setPaymentMethod(method);
                order.setPaymentTime(LocalDateTime.now());
                orderRepository.save(order);

                // 开通课程权限
                courseService.grantCourseAccess(order.getStudentId(), order.getCourseId());

                // 发送支付成功通知
                notificationService.triggerPaymentSuccessNotification(
                    order.getStudentId(), 
                    order.getCourseId(), 
                    order.getAmount()
                );
            }

            return order;
        } catch (PaymentException e) {
            order.setStatus(PaymentOrderStatus.FAILED);
            orderRepository.save(order);
            throw e;
        }
    }

    private void validateOrderBeforePayment(PaymentOrder order) {
        if (order.getStatus() != PaymentOrderStatus.PENDING) {
            throw new InvalidOrderStatusException("订单状态不可支付");
        }

        if (LocalDateTime.now().isAfter(order.getExpirationTime())) {
            order.setStatus(PaymentOrderStatus.EXPIRED);
            orderRepository.save(order);
            throw new OrderExpiredException("订单已超时");
        }
    }

    // 定时任务：每5分钟检查并取消超时订单
    @Scheduled(fixedRate = 5 * 60 * 1000)
    public void cancelExpiredOrders() {
        List<PaymentOrder> expiredOrders = orderRepository.findByStatusAndExpirationTimeBefore(
            PaymentOrderStatus.PENDING, 
            LocalDateTime.now()
        );

        expiredOrders.forEach(order -> {
            order.setStatus(PaymentOrderStatus.EXPIRED);
            orderRepository.save(order);
        });
    }

    public List<PaymentOrder> getStudentOrders(Long studentId) {
        return orderRepository.findByStudentId(studentId);
    }
}

// 支付方法枚举
enum PaymentMethod {
    WECHAT_PAY,
    ALIPAY,
    BANK_CARD,
    CREDIT_CARD
}

// 订单状态枚举
enum PaymentOrderStatus {
    PENDING,    // 待支付
    PAID,       // 已支付
    FAILED,     // 支付失败
    EXPIRED,    // 已过期
    REFUNDED    // 已退款
} 